using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Admin.NET.Application.Entity.Business;
using Admin.NET.Application.Service.Recharge.Dto;
using Admin.NET.Core;
using Admin.NET.Core.Service;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;

namespace Admin.NET.Application.Service.Recharge;

/// <summary>
/// 续约
/// </summary>
public class RechargeInfo : IDynamicApiController, ITransient, IPrivateDependency
{
	private readonly SqlSugarRepository<VolumeRecharge> _rep;

	private readonly UserManager _userManager;

	private readonly SysOnlineUserService _sysOnlineUserService;

	public RechargeInfo(SqlSugarRepository<VolumeRecharge> rep, UserManager userManager, SysOnlineUserService sysOnlineUserService)
	{
		_rep = rep;
		_userManager = userManager;
		_sysOnlineUserService = sysOnlineUserService;
	}

	/// <summary>
	/// 分页查询
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/rechargeInfo/page")]
	public async Task<dynamic> Page([FromQuery] RechargeInfoInput input)
	{
		ISugarQueryable<VolumeRecharge> query = _rep.Context.Queryable<VolumeRecharge>().WhereIF(!string.IsNullOrWhiteSpace(input.RechargeUserName), (VolumeRecharge u) => u.RechargeUserName.Contains(input.RechargeUserName.Trim())).WhereIF(input.AuditStatus.HasValue, (VolumeRecharge u) => (int?)u.AuditStatus == input.AuditStatus);
		return await query.ToPagedListAsync(input.Page, input.PageSize);
	}

	/// <summary>
	/// 分页查询
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/rechargeInfo/pageuser")]
	public async Task<dynamic> PageUser([FromQuery] RechargeInfoInput input)
	{
		ISugarQueryable<VolumeRecharge> query = _rep.Context.Queryable<VolumeRecharge>().WhereIF(!string.IsNullOrWhiteSpace(input.RechargeUserName), (VolumeRecharge u) => u.RechargeUserName.Contains(input.RechargeUserName.Trim())).WhereIF(input.AuditStatus.HasValue, (VolumeRecharge u) => (int?)u.AuditStatus == input.AuditStatus);
		return await query.ToPagedListAsync(input.Page, input.PageSize);
	}

	/// <summary>
	/// 新增
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/rechargeInfo/add")]
	public async Task AddRechargeInfo([FromBody] RechargeInfoAddInput input)
	{
		VolumeRecharge model = input.Adapt<VolumeRecharge>();
		model.TenantId = _userManager.TenantId;
		model.AuditStatus = 0;
		model.RechargeUser = _userManager.UserId;
		model.RechargeUserName = _userManager.RealName;
		await _rep.InsertAsync(model);
	}

	/// <summary>
	/// 根据Id查询
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/rechargeInfo/getId")]
	public async Task<dynamic> GetRechargeinfoId()
	{
		VolumeRecharge model = await (from u in _rep.Context.Queryable<VolumeRecharge>()
			where u.TenantId == (long?)_userManager.TenantId
			orderby u.CreateTime descending
			select u).FirstAsync();
		if (model == null || model.AuditStatus != 0)
		{
			return 0;
		}
		return model.Id;
	}

	/// <summary>
	/// 根据Id查询
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpGet("/rechargeInfo/rechargeId")]
	public async Task<dynamic> Rechargeinfo([FromQuery] BaseIdInput input)
	{
		return await _rep.GetFirstAsync((VolumeRecharge u) => u.Id == input.Id);
	}

	/// <summary>
	/// 初始化通知公告信息
	/// </summary>
	/// <param name="notice"></param>
	[NonAction]
	private void InitNoticeInfo(SysNotice notice)
	{
		notice.PublicUserId = _userManager.UserId;
		notice.PublicUserName = _userManager.RealName;
		notice.PublicOrgId = _userManager.OrgId;
	}

	/// <summary>
	/// 上报通知公告
	/// </summary>
	/// <param name="input">notice</param>
	/// <param name="userIdList">上报的id</param>
	/// <returns></returns>
	[NonAction]
	public async Task PublicNotice(NoticePublishInput input, List<long> userIdList)
	{
		SysNotice noticeInfo = input.Adapt<SysNotice>();
		InitNoticeInfo(noticeInfo);
		await _rep.Context.Insertable(noticeInfo).ExecuteCommandAsync();
		List<SysNoticeUser> noticeUserList = userIdList.Select((long u) => new SysNoticeUser
		{
			NoticeId = noticeInfo.Id,
			UserId = u
		}).ToList();
		await _rep.Context.Insertable(noticeUserList).ExecuteCommandAsync();
		await _sysOnlineUserService.PublicNotice(noticeInfo, userIdList);
	}

	/// <summary>
	/// 审核
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	[HttpPost("/rechargeInfo/examine")]
	public async Task RechargeExamine([FromBody] ExamineInput input)
	{
		try
		{
			VolumeRecharge model = await _rep.GetFirstAsync((VolumeRecharge u) => u.Id == input.Id);
			if (model == null)
			{
				throw Oops.Oh("当前审核数据异常请稍后再试!");
			}
			DateTime now = DateTime.Now;
			model.AuditStatus = input.Type;
			model.ExamineTime = now;
			model.RejectReason = input.AudioRemark;
			model.ExamineUser = _userManager.UserId;
			model.ExamineUserName = _userManager.RealName;
			await _rep.Context.Ado.BeginTranAsync();
			await _rep.Context.Updateable(model).UpdateColumns((VolumeRecharge u) => new { u.ExamineUserName, u.ExamineUser, u.AuditStatus, u.ExamineTime, u.RejectReason }).ExecuteCommandAsync();
			NoticePublishInput noticePublishInput = new NoticePublishInput
			{
				Status = NoticeStatusEnum.PUBLIC,
				CreateTime = now,
				Type = NoticeTypeEnum.NOTICE,
				PublicTime = now,
				PublicUserName = _userManager.RealName,
				PublicOrgId = _userManager.OrgId,
				Title = "续约审核结果"
			};
			if (model.AuditStatus == 1)
			{
				noticePublishInput.Content = "当前预约缴费审核不通过。失败原因" + input.AudioRemark;
			}
			else
			{
				SysTenant entity = await _rep.Context.Queryable<SysTenant>().FirstAsync((SysTenant u) => (long?)u.Id == model.TenantId);
				if (entity == null)
				{
					throw Oops.Oh("当前信息不存在，请联系管理员");
				}
				entity.VolumeEnd = model.RenewalContractTime;
				await _rep.Context.Updateable(entity).UpdateColumns((SysTenant u) => new { u.VolumeEnd }).ExecuteCommandAsync();
				noticePublishInput.Content = "当前预约缴费审核通过。请到后台个人中心查看确认！";
			}
			await PublicNotice(noticePublishInput, new List<long> { model.RechargeUser });
			await _rep.Context.Ado.CommitTranAsync();
		}
		catch (Exception)
		{
			await _rep.Context.Ado.RollbackTranAsync();
			throw;
		}
	}
}
